﻿/// <reference path="../../../../_3rd part/SharePoint.d.ts"/>

module spdevlab {

    export module fields {
        export class DateBirthField {

            _fieldName: string;
            _errorContainerId = null;

            _monthContainerId = "";
            _dayContainerId = "";
            _yearContainerId = "";

            constructor(fieldName: string) {
                this._fieldName = fieldName;
            }


            _onGetValue(): string {

                var result = '';

                var monthContainer = <HTMLSelectElement>document.getElementById(this._monthContainerId);
                var dayContainer = <HTMLSelectElement>document.getElementById(this._dayContainerId);
                var yearContainer = <HTMLSelectElement>document.getElementById(this._yearContainerId);

                var dValue = dayContainer.options[dayContainer.selectedIndex].value;
                var mValue = monthContainer.options[monthContainer.selectedIndex].value;
                var yValue = yearContainer.options[yearContainer.selectedIndex].value;

                if (dValue > -1 && mValue > -1 && yValue > -1) {
                    return mValue.toString() + "/" +
                        dValue.toString() + "/" +
                        yValue.toString();
                }

                return "";
            }

            _initValidators(renderCtx) {

                var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(renderCtx);

                var dbfFieldValidators = new SPClientForms.ClientValidation.ValidatorSet();

                if (formCtx.fieldSchema.Required) {
                    dbfFieldValidators.RegisterValidator(new spdevlab.fields.DateBirthFieldValidator());
                }

                formCtx.registerValidationErrorCallback(formCtx.fieldName, this.onError);
                formCtx.registerClientValidator(formCtx.fieldName, dbfFieldValidators);

            }

            _getDateTimeValue(fieldValue: string) {
                var result = {
                    activeDay: -1,
                    activeMonth: -1,
                    activeYear: -1
                };

                if (typeof fieldValue !== "undefined") {

                    var dateParts = [];

                    if (fieldValue.indexOf(":") > -1) {
                        dateParts = fieldValue.split(" ")[0].split('/');
                    }
                    else {
                        dateParts = fieldValue.split("/");
                    }

                    result.activeMonth = dateParts[0];
                    result.activeDay = dateParts[1];
                    result.activeYear = dateParts[2];
                }

                return result;

            }

            static _months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

            _getUI(monthContainerId, dayContainerId, yearContainerId, fieldValue) {
                var result = [];

                var timeValue = this._getDateTimeValue(fieldValue);
                var months = spdevlab.fields.DateBirthField._months;

                // month UI		
                result.push("<select id='" + monthContainerId + "' type='singleselect'>");
                result.push("<option value='-1'>Month...</option>");

                for (var i = 0; i < months.length; i++) {
                    var isSelected = (timeValue.activeMonth > -1 && (i + 1) == timeValue.activeMonth) == true ? "selected" : "";
                    result.push("<option value='" + (i + 1).toString() + "' " + isSelected + ">" + months[i].toString() + "</option>");
                }

                result.push("</select>");

                // day UI		
                result.push("<select id='" + dayContainerId + "' type='singleselect'>");
                result.push("<option value='-1'>Day...</option>");
                for (var i = 1; i <= 31; i++) {
                    var isSelected = (timeValue.activeDay > -1 && (i) == timeValue.activeDay) == true ? "selected" : "";
                    result.push("<option value='" + i.toString() + "' " + isSelected + ">" + i.toString() + "</option>");
                }
                result.push("</select>");

                result.push(" | ");

                // year UI		
                result.push("<select id='" + yearContainerId + "' type='singleselect'>");
                result.push("<option value='-1'>Choose...</option>");
                for (var i = 2013; i >= 1905; i--) {
                    var isSelected = (timeValue.activeYear > -1 && (i) == timeValue.activeYear) == true ? "selected" : "";
                    result.push("<option value='" + i.toString() + "' " + isSelected + ">" + i.toString() + "</option>");
                }
                result.push("</select>");

                return result.join("");
            }

            newFormTemplate(renderCtx): string {

                this._initValidators(renderCtx);

                var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(renderCtx);
                formCtx.registerGetValueCallback(formCtx.fieldName, () => { return this._onGetValue(); });

                var containerId = formCtx.fieldName + '_' + formCtx.fieldSchema.Id + 'DateBirth_Field';

                this._monthContainerId = containerId + "_Month";
                this._dayContainerId = containerId + "_Day";
                this._yearContainerId = containerId + "_Year";

                return this._getUI(this._monthContainerId, this._dayContainerId, this._yearContainerId) + this._wrapErrorArea(renderCtx);

            }

            editFormTemplate(renderCtx): string {
                var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(renderCtx);
                var fieldValue = renderCtx.CurrentItem[renderCtx.CurrentFieldSchema.Name];

                this._initValidators(renderCtx);

                var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(renderCtx);
                formCtx.registerGetValueCallback(formCtx.fieldName, () => { return this._onGetValue(); });

                var containerId = formCtx.fieldName + '_' + formCtx.fieldSchema.Id + 'DateBirth_Field';

                this._monthContainerId = containerId + "_Month";
                this._dayContainerId = containerId + "_Day";
                this._yearContainerId = containerId + "_Year";

                return this._getUI(this._monthContainerId, this._dayContainerId, this._yearContainerId, fieldValue) + this._wrapErrorArea(renderCtx);

            }

            displayFormTemplate(renderCtx): string {
                if (renderCtx != null && renderCtx.CurrentFieldValue != null) {

                    var fieldValue = renderCtx.CurrentFieldValue.toString();

                    var timeValue = this._getDateTimeValue(fieldValue);

                    if (timeValue.activeDay > -1 && timeValue.activeMonth > -1 && timeValue.activeYear > -1) {
                        return spdevlab.fields.DateBirthField._months[timeValue.activeMonth - 1].toString() + " " +
                            timeValue.activeDay.toString() + ", " +
                            timeValue.activeYear.toString();
                    }

                    return fieldValue;
                }

                return '';

            }

            viewTemplate(renderCtx, field, listItem, listSchema) {

                var fieldValue = "";

                if (renderCtx != null && renderCtx.CurrentItem != null) {
                    fieldValue = renderCtx.CurrentItem[field.Name];
                    var timeValue = this._getDateTimeValue(fieldValue);

                    if (timeValue.activeDay > -1 && timeValue.activeMonth > -1 && timeValue.activeYear > -1) {
                        return spdevlab.fields.DateBirthField._months[timeValue.activeMonth - 1].toString() + " " +
                            timeValue.activeDay.toString() + ", " +
                            timeValue.activeYear.toString();
                    }
                }

                return fieldValue;
            }

            _wrapErrorArea(renderCtx) {
                var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(renderCtx);
                var errorContainerId = formCtx.fieldName + '_' + formCtx.fieldSchema.Id + '_DateBirth_Error';

                this._errorContainerId = errorContainerId;

                return "<div></div><span id='" + errorContainerId + "' class='ms-formvalidation ms-csrformvalidation'></span>";

            }

            onError(error) {
                if (this._errorContainerId != null) {

                    document
                        .getElementById(this._errorContainerId)
                    .innerHTML = "<span role='alert'>" + error.errorMessage + "</span>";
                }
            }

            Init() {

                var fieldName = this._fieldName;
                var visaFieldTemplates = {
                    Templates: {
                        Fields: {}
                    }
                };

                visaFieldTemplates.Templates.Fields[fieldName] = {};

                visaFieldTemplates.Templates.Fields[fieldName]["View"] = (renderCtx, field, listItem, listSchema) => {
                    return this.viewTemplate(renderCtx, field, listItem, listSchema);
                };

                visaFieldTemplates.Templates.Fields[fieldName]["NewForm"] = (renderCtx) => {
                    return this.newFormTemplate(renderCtx);
                };

                visaFieldTemplates.Templates.Fields[fieldName]["EditForm"] = (renderCtx) => {
                    return this.editFormTemplate(renderCtx);
                };

                visaFieldTemplates.Templates.Fields[fieldName]["DisplayForm"] = (renderCtx) => {
                    return this.displayFormTemplate(renderCtx);
                };

                SPClientTemplates.TemplateManager.RegisterTemplateOverrides(visaFieldTemplates);
            }
        }

        export class DateBirthFieldValidator {

            Validate(value: string): SPClientForms.ClientValidation.ValidationResult {

                var hasError = value == "";
                var errorMsg = hasError ? "Please, fill out birthdate." : '';

                return new SPClientForms.ClientValidation.ValidationResult(hasError, errorMsg);

            }
        }
    }
}

(function () {
    var field = new spdevlab.fields.DateBirthField("DateBirthField");
    field.Init();
})();